package com.example.friendcash.activities;

import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Color;
import android.graphics.Typeface;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.SectionIndexer;
import android.widget.TextView;
import com.example.friendcash.R;
import com.example.friendcash.custom.indexablelist.IndexableListView;
import com.example.friendcash.custom.indexablelist.StringMatcher;
import com.example.friendcash.database.core.Contact;
import com.example.friendcash.utils.collections.Sequences;
import com.example.friendcash.utils.functions.IIn;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static android.provider.BaseColumns._ID;
import static android.provider.ContactsContract.Contacts.CONTENT_URI;
import static android.provider.ContactsContract.Contacts.DISPLAY_NAME;
import static android.provider.ContactsContract.Contacts.HAS_PHONE_NUMBER;
import static android.provider.ContactsContract.Contacts.STARRED;

public class PickFriendsActivity extends AbsMenuActivity {

    private final String mSections = "#ABCDEFGHIJKLMNOPQRSTUVWXYZАБВГДЕЄЖЗИІЙКЛМНОПРСТУФХЦЧШЩЮЯ";

    private final static String[] PROJECTION = new String[]{_ID, DISPLAY_NAME, STARRED};
    private final static String SELECTION = HAS_PHONE_NUMBER + " = '1'";

    private ContentAdapter adapter;

    final List<Contact> contacts = new ArrayList<Contact>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.pick_friends_activity);
        setupOverflowMenu(R.menu.pick_friends, findViewById(R.id.pick_friend_menu));
        final IndexableListView listView = (IndexableListView) findViewById(R.id.listview);
        final View newFriendButton = findViewById(R.id.pick_friend_new_friend);
        newFriendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                final Intent intent = new Intent(PickFriendsActivity.this, NewEventActivity.class);
                startActivityForResult(intent, 0);
            }
        });
        adapter = new ContentAdapter(this, android.R.layout.simple_list_item_1, contacts);
        listView.setAdapter(adapter);
        listView.setFastScrollEnabled(true);
        loader.loadAndShow(SELECTION);
    }

    interface ILoader {
        void loadAndShow(String condition);
    }

    private final ILoader loader = new ILoader() {
        @Override
        public void loadAndShow(final String condition) {
            final Map<String, String> result = getContacts(condition);
            contacts.clear();
            final List<String> collection = new ArrayList<String>(result.keySet());
            Collections.sort(collection, comparator);
            Sequences.each(collection, addElementFunctor);
            if (adapter != null) {
                initHeaders(contacts);
                adapter.notifyDataSetChanged();
            }
        }
    };

    private static final Comparator<String> comparator = new Comparator<String>() {
        @Override
        public int compare(String first, String second) {
            return first.compareTo(second);
        }
    };

    private final IIn<String> addElementFunctor = new IIn<String>() {
        @Override
        public void in(String name) {
            contacts.add(new Contact(name, false));
        }
    };

    private void initHeaders(List<Contact> contacts) {
        for (int i = 0; i < mSections.length(); i++) {
            final char character = mSections.charAt(i);
            for (Contact item : contacts) {
                if (Character.toLowerCase(item.name.charAt(0)) == Character.toLowerCase(character)) {
                    final int index = contacts.indexOf(item);
                    contacts.add(index, new Contact(Character.toString(character), true));
                    break;
                }
            }
        }
    }

    private Map<String, String> getContacts(String condition) {
        final Map<String, String> contactMap = new HashMap<String, String>();
        final ContentResolver cr = getContentResolver();
        final Cursor cursor = cr.query(CONTENT_URI, PROJECTION, condition, null, null);
        while (cursor.moveToNext()) {
            final String contactID = cursor.getString(cursor.getColumnIndex(_ID));
            final Intent intent = new Intent(Intent.ACTION_VIEW);
            final Uri uri = Uri.withAppendedPath(CONTENT_URI, String.valueOf(contactID));
            intent.setData(uri);
            final String title = (cursor.getString(cursor.getColumnIndex(DISPLAY_NAME)));
            contactMap.put(title, intent.toUri(0));
        }
        cursor.close();
        return contactMap;
    }

    private class ContentAdapter extends ArrayAdapter<Contact> implements SectionIndexer {

        private final int ITEM_FRIENDS = 0;
        private final int ITEM_EMPTY = 1;

        private final List<Contact> contacts;

        public ContentAdapter(Context context, int textViewResourceId,
                              List<Contact> objects) {
            super(context, textViewResourceId, objects);
            this.contacts = objects;
        }

        @Override
        public int getPositionForSection(int section) {
            // If there is no item for current section, previous section will be selected
            for (int i = section; i >= 0; i--) {
                for (int j = 0; j < getCount(); j++) {
                    if (i == 0) {
                        // For numeric section
                        for (int k = 0; k <= 9; k++) {
                            if (StringMatcher.match(String.valueOf(getItem(j).name.charAt(0)), String.valueOf(k)))
                                return j;
                        }
                    } else {
                        if (StringMatcher.match(String.valueOf(getItem(j).name.charAt(0)), String.valueOf(mSections.charAt(i))))
                            return j;
                    }
                }
            }
            return 0;
        }

        @Override
        public int getSectionForPosition(int position) {
            return 0;
        }

        @Override
        public int getCount() {
            return contacts.size() > 0 ? contacts.size() : contacts.size() + 1;
        }

        @Override
        public int getViewTypeCount() {
            return 2;
        }

        @Override
        public int getItemViewType(int position) {
            return position < contacts.size() ? ITEM_FRIENDS : ITEM_EMPTY;
        }

        @Override
        public Object[] getSections() {
            String[] sections = new String[mSections.length()];
            for (int i = 0; i < mSections.length(); i++)
                sections[i] = String.valueOf(mSections.charAt(i));
            return sections;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if (getItemViewType(position) == ITEM_FRIENDS) {
                final Contact contact = contacts.get(position);
                final TextView view = (TextView) super.getView(position, convertView, parent);
                view.setTextColor(Color.WHITE);
                if (contact.isHeader) {
                    view.setBackgroundColor(Color.rgb(220, 127, 127));
                    view.setTypeface(null, Typeface.BOLD);
                } else {
                    view.setBackgroundColor(Color.BLACK);
                    view.setTypeface(null, Typeface.NORMAL);
                }
                view.setTextSize(16);
                view.setMaxLines(2);
                view.setText(contact.name);
                return view;
            } else if (getItemViewType(position) == ITEM_EMPTY) {
                final LinearLayout layout = (LinearLayout) getLayoutInflater()
                        .inflate(R.layout.add_friends_from_contacts, null);
                final TextView textView = (TextView) layout.findViewById(R.id.addFriendsFromContact);
                textView.setText(getString(R.string.no_contacts_found));
                layout.setClickable(false);
                layout.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        final Intent intent = new Intent(PickFriendsActivity.this, PickFriendsActivity.class);
                        startActivity(intent);
                    }
                });
                return layout;
            }
            return convertView;
        }
    }

}
